﻿namespace Beetle
{
    using System;
    using System.Runtime.CompilerServices;
    using System.Threading;

    public abstract class Task : IDisposable
    {
        private Timer _field_a;
        private int _field_b;
        private int _field_c;
        private Exception _field_d;
        private bool _field_e;

        public Task()
        {
            this.IsDisposed =(false);
        }

        private void a()
        {
            if ((this._field_a != null) && !this.IsDisposed)
            {
                this._field_a.Change(this._field_b, this._field_c);
            }
        }

        private void a(object A_0)
        {
            this.b();
            this.a((Exception) null);
            try
            {
                this.Execute();
            }
            catch (Exception exception)
            {
                this.a(exception);
            }
            finally
            {
                this.a();
            }
        }

        private void b()
        {
            if ((this._field_a != null) && !this.IsDisposed)
            {
                this._field_a.Change(-1, -1);
            }
        }

        public void Dispose()
        {
            lock (this)
            {
                if (!this.IsDisposed)
                {
                    this.a(true);
                }
                if (this._field_a != null)
                {
                    this._field_a.Dispose();
                }
            }
        }

        protected abstract void Execute();
        public void Start(int dueTime, int period)
        {
            lock (this)
            {
                if (!this.IsDisposed)
                {
                    this._field_b = dueTime;
                    this._field_c = period;
                    this._field_a = new Timer(new TimerCallback(this.a), null, dueTime, period);
                }
            }
        }

        public Exception Error
        {
            get
            {
                return this._field_d;
            }
            internal set
            {
                this._field_d = value;
            }
        }

        public bool IsDisposed
        {
            get
            {
                return this._field_e;
            }
            private set
            {
                this._field_e = value;
            }
        }
    }
}

